#ifndef MINESWEEPRWIDGET_H
#define MINESWEEPRWIDGET_H

#include <QWidget>
#include <QVector>

#include <memory>

#include "cell.h"
#include "player.h"

// #include "tcp_client.h"

class tcp_client;

struct Position {
    explicit Position(int row = 0, int col = 0) : row_(row), col_(col) { }
    int row_;
    int col_;
};

enum PlayerIndex {
    PlayerIndexSystem = 0,
    PlayerIndex1 = 1,
    PlayerIndex2 = 2,
    PlayerIndexMax,
};

class GameWidget;

class MineSweeprWidget : public QWidget
{
    Q_OBJECT
public:
    explicit MineSweeprWidget(QWidget *parent = nullptr);

    // 处理本机鼠标信号，向服务器发送对应的操作信息
    void mousePressEvent(QMouseEvent* event);
    int rowNum() const
    {
        return grids_.size();
    }

    int colNum() const
    {
        if (grids_.empty()) {
            return 0;
        }
        return grids_[0].size();
    }

    void setTcpClient(std::shared_ptr<tcp_client> clientPtr)
    {
        clientPtr_ = clientPtr;
    }

    /* 处理服务器事件 */
    /* 处理服务器发过来的鼠标左键点击事件，既可能是自己也可能是对方玩家点击结果的回传 */
    void onRemoteLeftButtonClicked(bool isOpponent, const QVector<Position> &positions);

    void onInitGame(uint8_t playerIndex, const QVector<Position> &bombsPosition,
        const QVector<Position> &positionsOpenedByServer);

    void setPlayerIndex(uint8_t playerIndex)
    {
        playerIndex_ = playerIndex;
    }
    uint8_t playerIndex() const
    {
        return playerIndex_;
    }

    bool IsGameInited() const
    {
        return isGameInited_;
    }

    void reset()
    {
        for (int i = 0; i < rowNum(); i++) {
            for (int j = 0; j < colNum(); j++) {
                grids_[i][j]->reset();
            }
        }
        playerIndex_ = 0;
        isGameInited_ = false;
    }

    Player &player1()
    {
        return player1_;
    }

    Player &player2()
    {
        return player2_;
    }

    Player &getOpponentPlayer()
    {
        if (playerIndex_ == PlayerIndex1) {
            return player2_;
        } else if (playerIndex_ == PlayerIndex2) {
            return player1_;
        }
        return player1_;
    }

    Player &getSelfPlayer()
    {
        if (playerIndex_ == PlayerIndex1) {
            return player1_;
        } else if (playerIndex_ == PlayerIndex2) {
            return player2_;
        }
        return player1_;
    }

    void setGameWidget(std::shared_ptr<GameWidget> gameWidget);

signals:

private:
    bool isPositionValid(const Position &pos)
    {
        if (pos.col_ < 0 || pos.col_ >= colNum() || pos.row_ < 0 || pos.row_ >= rowNum()) {
            return false;
        }

        return true;
    }

    std::shared_ptr<Cell> cellAtPos(const Position &pos)
    {
        if (!isPositionValid(pos)) {
            return nullptr;
        }
        return grids_[pos.row_][pos.col_];
    }

    void calculateBombsAround();

    /* 处理本机事件 */
    void onLocalLeftButtonClicked(const Position &pos);
    void onLocalRightButtonClicked(const Position &pos);
    void onLocalLeftRightButtonClicked(const Position &pos);

    QVector<QVector<std::shared_ptr<Cell>>> grids_;

    std::shared_ptr<tcp_client> clientPtr_ = nullptr;
    bool isGameInited_ = false;
    uint8_t playerIndex_ = 0;   /* 被分配的玩家编号 @ref PlayerIndex */

    Player player1_;
    Player player2_;

    std::weak_ptr<GameWidget> gameWidget_;
};

#endif // MINESWEEPRWIDGET_H
